<!DOCTYPE html>
<!--
Explore on-the-fly properties similar to C#
Mainly based on http://stackoverflow.com/questions/3208571/create-javascript-property-like-c-sharp-property
and my research.

Research not fully done as it becomes very complicated for what we need but "properties" look promissing.

Links for further readin:
    @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
    @see http://ejohn.org/blog/ecmascript-5-objects-and-properties/#postcomment

Conclusions:
    1. If property added with defineProperty()/classic on prototype:
        - hasOwnProperty() returns false
        - "in" returns true
    2. If property added with defineProperty()/classic on instance:
        - hasOwnProperty() returns true
        - "in" returns true
-->
<html>
    <head>
        <title>On-the-fly object properties</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script type="text/javascript">

            //Class property. Trying to add a property to an object
            function A() {
                this.prop0 = 9;
            }
            
            A.prototype = {
                constructor: A,
//                prop0: 'zero'
            };
            
            //Attach a property to class A
            Object.defineProperty(A.prototype, "lineDashOffset", {
                    get: function() {
                        console.info("lineDashOffset get");
                        return this.val;
                    },
                    set: function(val) {
                        console.info("lineDashOffset set");
                        this.val = val;
                    }
            });
            
            
            function testPropertyForInstance(){
                //Instance property. Add a property to an object's instance
                var obj = {};
                Object.defineProperty(obj, "value", {
                    get: function() {
                        console.info("Value get");
                        return this.val;
                    },
                    set: function(val) {
                        console.info("Value set");
                        this.val = val;
                    }
                });
                
                obj.value = "ola";                
                var x = obj.value;
            }
            
            
            function testPropertyForClass(){
                //Test class property
                var a = new A();
                a.lineDashOffset = 5;
                var v = a.lineDashOffset;
            }
            
            function testAddedProp(){
                
                //add 1st property - Added to prototype
                Object.defineProperty(A.prototype, 'prop1',{
                    set : function(val){
                        
                    },
                    
                    get : function(){
                        
                    },
                    
                    enumerable :true
                });
                
                //add 2nd property
                Object.defineProperty(A.prototype, 'prop2', 
                        {
                            value: 7,
                            writable: true
                        }
                );
                  
                  
                //add 2nd property - Added to object  
                var a = new A();               
                Object.defineProperty(a, 'prop3', 
                        {
                            value: 3,
                            writable: true
                        }
                );
        
                //added to object - the old way
                a.prop4 = "4";
                
                //added to prototype - the old way
                A.prototype.prop5 = "5";
                
               console.info("a owns prop0: " + a.hasOwnProperty('prop0'));
               console.info("a has prop0: " + ('prop0' in a));
               
               console.info("a owns prop1: " + a.hasOwnProperty('prop1'));
               console.info("a has prop1: " + ('prop1' in a));
               
               console.info("a owns prop2: " + a.hasOwnProperty('prop2'));
               console.info("a has prop2: " + ('prop2' in a));
               
               console.info("a owns prop3: " + a.hasOwnProperty('prop3'));
               console.info("a has prop3: " + ('prop3' in a));
               
               console.info("a owns prop4: " + a.hasOwnProperty('prop4'));
               console.info("a has prop4: " + ('prop4' in a));
               
               console.info("a owns prop5: " + a.hasOwnProperty('prop5'));
               console.info("a has prop5: " + ('prop5' in a));
            }

            function pageLoaded() {
                console.info("Loaded");

                
                //testPropertyForClass();
                
//                var o = {};
//                o.name = 'Nisa';
//                console.info("O object has 'name' as property: " + o.hasOwnProperty('name'))
//                console.info("O object has 'toString' as property: " + o.hasOwnProperty('toString'))
                testAddedProp();
            }
            
            

            window.addEventListener("load", pageLoaded, false);
        </script>
    </head>
    <body>
        <div>
            <canvas id="quilt" width="300" height="300"></canvas>
        </div>
    </body>
</html>
